home *** CD-ROM | disk | FTP | other *** search
/ Amiga Developer CD 2.1 / Amiga Developer CD v2.1.iso / NDK / NDK_3.1 / Examples1 / PCMCIA / AmigaXIP / loadseg.asm < prev    next >
Encoding:
Assembly Source File  |  1993-01-08  |  12.2 KB  |  589 lines

  1.  
  2.     INCLUDE    "exec/types.i"
  3.     INCLUDE    "exec/ables.i"
  4.     INCLUDE    "exec/memory.i"
  5.     INCLUDE    "libraries/dos.i"
  6.  
  7. ABSEXECBASE    EQU    4
  8.     
  9.     XDEF    _PrivateLoadSeg
  10.  
  11.     XREF    _intena
  12.  
  13.     XREF    _LVOAllocMem
  14.     XREF    _LVOAllocAbs
  15.     XREF    _LVOClose
  16.     XREF    _LVOCloseLibrary
  17.     XREF    _LVOFreeMem
  18.     XREF    _LVOOpen
  19.     XREF    _LVOOpenLibrary
  20.     XREF    _LVORead
  21.  
  22. MAXNAMELEN    EQU    128
  23.  
  24. HUNK_HEADER    EQU    1011
  25.  
  26.  
  27. ;------    LoadSeg ------------------------------------------------------
  28. ;
  29. ;   NAME
  30. ;    LoadSeg - load a file into memory and relocate it
  31. ;
  32. ;   SYNOPSIS
  33. ;    success = LoadSeg(allocFunc, freeFunc, readFunc,
  34. ;    d0                a0         a1        a2
  35. ;                      readHandle, dataEnviron)
  36. ;                      d1          a6
  37. ;
  38. ;    actual = readFunc(readHandle, buffer, length)
  39. ;       d0                d1          a0      d0
  40. ;
  41. ;    memory = allocFunc(size, flags)
  42. ;    d0                 d0    d1
  43. ;
  44. ;    freeFunc(memory, size)
  45. ;             a1      d0
  46. ;
  47. ;   EXCEPTIONS
  48. ;    This LoadSeg fails if resident or overlay hunks exist.
  49. ;
  50. ;---------------------------------------------------------------------
  51. lsv_DataEnviron    EQU    0        ; function argument passed in a6
  52. lsv_ReadFunc    EQU    lsv_DataEnviron-4
  53. lsv_FreeFunc    EQU    lsv_ReadFunc-4
  54. lsv_AllocFunc    EQU    lsv_FreeFunc-4
  55. lsv_ReadHandle    EQU    lsv_AllocFunc-4
  56. lsv_Segment    EQU    lsv_ReadHandle-4
  57. lsv_Name    EQU    lsv_Segment-MAXNAMELEN
  58. lsv_LINKSIZE    EQU    lsv_Name-4
  59.  
  60. ;
  61. ;   d2    various temporaries
  62. ;   d3    hunk relocation offset value
  63. ;   d4    byte limit of current hunk
  64. ;   d5    first hunk slot
  65. ;   d6    last hunk slot
  66. ;   a2    current hunk address
  67. ;   a3    segment tail
  68. ;   a4    hunk table
  69. ;   a5    lsv structure
  70. ;   a6    scratch data area
  71. ;
  72. LoadSeg:
  73.         movem.l    d2-d6/a2-a5,-(a7)
  74.         link    a6,#lsv_LINKSIZE
  75.         move.l    a6,a5
  76.  
  77.         movem.l    d1/a0/a1/a2,lsv_ReadHandle(a5)
  78.         moveq    #0,d6
  79.         move.l    d6,lsv_Segment(a5)
  80.         move.l    d6,a4
  81.  
  82.         ;-- ensure this is a valid load file
  83.         bsr    GetLong
  84.         cmp.l    #HUNK_HEADER,d0
  85.         bne    lsFail
  86.  
  87.         ;-- handle resident library header by failing if it exists
  88.         bsr    GetLong
  89.         tst.l    d0
  90.         bne    lsFail
  91.  
  92.         ;-- handle hunks
  93.         bsr    GetLong        ; get table size
  94.         bsr    GetLong        ; get first hunk slot
  95.         move.l    d0,d5
  96.         bsr    GetLong        ; get last hunk slot
  97.         move.l    d0,d6
  98.  
  99.         ;-- allocate the temporary hunk table via Exec AllocMem
  100.         addq.l    #1,d0        ; last slot + 1 long words
  101.         lsl.l    #2,d0        ; in bytes
  102.         moveq    #0,d1
  103.         move.l    ABSEXECBASE,a6
  104.         jsr    _LVOAllocMem(a6)
  105.         tst.l    d0
  106.         beq    lsFail
  107.         move.l    d0,a4
  108.  
  109.         ;-- allocate the hunks themselves
  110. lsAllocHunks:
  111.         move.w    d5,d2
  112.         lsl.w    #2,d5
  113.         lea    0(a4,d5.w),a2
  114.         lea    lsv_Segment(a5),a3
  115. lsAllocHunk:
  116.         ;-- for each entry in this file
  117.         cmp.w    d6,d2
  118.         bgt.s    lsLoadHunks
  119.         ;-- allocate space for the hunk and cache pointer in the table    
  120.         bsr    GetLong        ; get size needed
  121.         beq.s    lsEmptyHunk
  122.         bsr    GetVector    ; get memory
  123.         move.l    a0,(a2)+    ; cache pointer
  124.         move.l    a0,d0        ; convert
  125.         lsr.l    #2,d0        ;   to BPTR
  126.         move.l    d0,(a3)        ;   and link to end of segment
  127.         move.l    a0,a3        ; new tail
  128. lsNextHunk:
  129.         addq.w    #1,d2        ; count up hunk
  130.         bra.s    lsAllocHunk
  131.  
  132. lsEmptyHunk:
  133.         clr.l    (a2)+
  134.         bra.s    lsNextHunk
  135.  
  136.         ;-- read in the load image
  137. lsLoadHunks:
  138.         moveq    #-1,d4            ; byte limit: between hunks
  139. lsLoadHunk:
  140.         ;-- perform GetLong-like function, but EOF is OK here
  141.         subq.l    #4,a7
  142.         move.l    a7,a0
  143.         moveq    #4,d0
  144.         move.l    lsv_ReadHandle(a5),d1
  145.         movem.l    lsv_ReadFunc(a5),a1/a6
  146.         jsr    (a1)
  147.         tst.l    d0            ; check for EOF
  148.         beq    lsFreeHunk
  149.         cmp.l    #4,d0
  150.         bne    lsFail
  151.         ;-- switch on hunk type
  152.         move.l    (a7)+,d0
  153.         andi.l    #$3fffffff,d0
  154.         sub.l    #1000,d0
  155.         bmi    lsFail
  156.         cmp.l    #HUNKSWITCHLIMIT,d0
  157.         bge    lsFail
  158.         add.w    d0,d0
  159.         move.w    lsSwitch(pc,d0.w),d0
  160.         jsr    lsSwitch(pc,d0.w)
  161.         bra.s    lsLoadHunk
  162.  
  163. lsSwitch:
  164.         dc.w    lssHunkName-lsSwitch
  165.         dc.w    lssHunkCode-lsSwitch
  166.         dc.w    lssHunkData-lsSwitch
  167.         dc.w    lssHunkBSS-lsSwitch
  168.         dc.w    lssHunkReloc32-lsSwitch
  169.         dc.w    lssHunkReloc16-lsSwitch
  170.         dc.w    lssHunkReloc8-lsSwitch
  171.         dc.w    lssHunkExt-lsSwitch
  172.         dc.w    lssHunkSymbol-lsSwitch
  173.         dc.w    lssHunkDebug-lsSwitch
  174.         dc.w    lssHunkEnd-lsSwitch
  175.         dc.w    lssHunkHeader-lsSwitch
  176.         dc.w    lssHunkCont-lsSwitch
  177.         dc.w    lssHunkOverlay-lsSwitch
  178.         dc.w    lssHunkBreak-lsSwitch
  179.  
  180. HUNKSWITCHLIMIT    EQU    (*-lsSwitch)/2
  181.  
  182. ; . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
  183. lssHunkName:
  184.         bsr    ReadName        ; read name
  185.         rts                ; and ignore
  186.  
  187. ; . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
  188. lssHunkCode:
  189. lssHunkData:
  190.         ;-- get hunk size
  191.         bsr    GetLong
  192.         ;-- get new byte limit
  193.         lsl.l    #2,d0
  194.         move.l    d0,d4
  195.         subq.l    #4,d4
  196.         ;-- get hunk base
  197.         move.l    0(a4,d5.w),a2        ; get table entry
  198.         addq.l    #4,a2            ; skip next segment pointer
  199.         addq.l    #4,d5            ; bump hunk number
  200.         ;-- load in the code
  201.         move.l    d0,d2
  202.         beq.s    lsshdReturn
  203.         move.l    a2,a0
  204.         move.l    lsv_ReadHandle(a5),d1
  205.         movem.l    lsv_ReadFunc(a5),a1/a6
  206.         jsr    (a1)
  207.         cmp.l    d2,d0
  208.         bne    lssFail
  209. lsshdReturn:
  210.         rts
  211.  
  212. ; . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
  213. lssHunkBSS:
  214.         ;-- get hunk size
  215.         bsr    GetLong
  216.         ;-- get new byte limit
  217.         move.l    d0,d4
  218.         lsl.l    #2,d4
  219.         subq.l    #4,d4
  220.         ;-- get hunk base
  221.         move.l    0(a4,d5.w),a2        ; get table entry
  222.         addq.l    #4,a2            ; skip next segment pointer
  223.         addq.l    #4,d5            ; bump hunk number
  224.         ;-- clear the bss area
  225.         move.l    a2,a0
  226.         moveq    #0,d1
  227.         move.w    d0,d2            ; low word
  228.         swap    d0            ; high word
  229.         bra.s    lsshbssDBF
  230. lsshbssLoop:
  231.         move.l    d1,(a0)+
  232. lsshbssDBF:
  233.         dbf    d2,lsshbssLoop
  234.         dbf    d0,lsshbssLoop
  235.         rts
  236.  
  237. ; . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
  238. lssHunkReloc32:
  239.         bsr    GetLong
  240.         move.w    d0,d2
  241.         beq.s    lsshrReturn
  242.         bsr    GetLong
  243.         cmp.l    d6,d0
  244.         bgt.s    lssFail
  245.  
  246.         lsl.w    #2,d0
  247.         move.l    0(a4,d0.w),d3        ; get table entry
  248.         addq.l    #4,d3            ; skip next segment pointer
  249.         subq.w    #1,d2
  250. lsshrRelocLoop:
  251.         bsr    GetLong
  252.         ;-- ensure within hunk
  253.         bmi.s    lssFail
  254.         cmp.l    d4,d0
  255.         bgt.s    lssFail
  256.         add.l    d3,0(a2,d0.l)        ; add base to offset
  257.         dbf    d2,lsshrRelocLoop
  258.         bra.s    lssHunkReloc32
  259.  
  260. lsshrReturn:
  261.         rts
  262.  
  263. ; . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
  264. lssHunkSymbol:
  265.         bsr    ReadName        ; flush symbol name
  266.         tst.l    d0            ; check symbol length
  267.         beq.s    lsshsDone        ; end of symbol hunk if zero
  268.         bsr    GetLong            ; flush symbol value
  269.         bra.s    lssHunkSymbol
  270. lsshsDone:
  271.         rts
  272.  
  273. ; . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
  274. lssHunkDebug:
  275.         bsr    GetLong
  276.         move.w    d0,d2
  277.         bra.s    lsshdDBF
  278. lsshdLoop:
  279.         bsr    GetLong
  280. lsshdDBF:
  281.         dbf    d2,lsshdLoop
  282.         rts
  283.  
  284. ; . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
  285. lssHunkEnd:
  286.         moveq    #-1,d4        ; flag end in limit
  287.         rts            ; (it's OK to see EOF now)
  288.  
  289. ; . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
  290. lssFail:
  291. lssHunkReloc16:
  292. lssHunkReloc8:
  293. lssHunkExt:
  294. lssHunkHeader:
  295. lssHunkCont:
  296. lssHunkOverlay:
  297. lssHunkBreak:
  298.         moveq    #0,d4        ; flag error
  299.         addq.l    #4,a7        ; pop switch return address
  300.                     ; fall thru to lsFreeHunk
  301. ; . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
  302.  
  303. lsFreeHunk:
  304.         move.l    a4,d0
  305.         beq.s    lsCheckOK
  306.         ;-- free the temporary hunk table via Exec FreeMem
  307.         move.l    d6,d0        ; recover last slot
  308.         addq.l    #1,d0        ; last slot + 1 long words
  309.         lsl.l    #2,d0        ; in bytes
  310.         move.l    a4,a1
  311.         move.l    ABSEXECBASE,a6
  312.         jsr    _LVOFreeMem(a6)
  313.  
  314.         ;-- check for error
  315. lsCheckOK:
  316.         cmp.l    #-1,d4
  317.         beq.s    lsOK
  318.  
  319.         ;-- unload the segment
  320.         move.l    lsv_Segment(a5),d1
  321.         move.l    lsv_FreeFunc(a5),a1
  322.         move.l    lsv_DataEnviron(a5),a6
  323.         bsr    UnLoadSeg
  324.         moveq    #0,d0
  325.         bra.s    lsReturn
  326.  
  327. lsOK:
  328.         ;-- return list head BPTR as result
  329.         move.l    lsv_Segment(a5),d0
  330.  
  331. lsReturn:
  332.         move.l    a5,a6
  333.         unlk    a6
  334.         movem.l    (a7)+,d2-d6/a2-a5
  335.         rts
  336.  
  337. lsFail:
  338.         moveq    #0,d4
  339.         bra.s    lsFreeHunk
  340.  
  341. ; - - -    GetLong - - - - - - - - - - - - - - - - - - - - - - - - - - -
  342. ;
  343. ;   INPUT
  344. ;   a4    readHandle
  345. ;   a4    readFunc
  346. ;
  347. ;   RESULT
  348. ;   d0    next longword in stream
  349. ;
  350. ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  351. GetLong:
  352.         subq.l    #4,a7
  353.         move.l    a7,a0
  354.         moveq    #4,d0
  355.         move.l    lsv_ReadHandle(a5),d1
  356.         movem.l    lsv_ReadFunc(a5),a1/a6
  357.         jsr    (a1)
  358.         cmp.l    #4,d0
  359.         bne.s    gFail
  360.         move.l    (a7)+,d0
  361.         rts
  362.  
  363.  
  364. ; - - -    ReadName  - - - - - - - - - - - - - - - - - - - - - - - - - -
  365. ;
  366. ;   INPUT
  367. ;   a5    lsv structure
  368. ;
  369. ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  370. ReadName:
  371.         bsr.s    GetLong
  372.         lsl.l    #2,d0
  373.         beq.s    rnReturn
  374.         cmp.l    #MAXNAMELEN,d0
  375.         bge.s    rnFail
  376.         lea    lsv_Name(a5),a0
  377.         move.l    d0,-(a7)
  378.         move.l    lsv_ReadHandle(a5),d1
  379.         movem.l    lsv_ReadFunc(a5),a1/a6
  380.         jsr    (a1)
  381.         cmp.l    (a7)+,d0
  382.         bne.s    rnFail
  383. rnReturn:
  384.         rts
  385. rnFail:
  386.         addq.l    #4,a7
  387.         bra.s    lsFail
  388.  
  389.  
  390. ; - - -    GetVector - - - - - - - - - - - - - - - - - - - - - - - - - -
  391. ;
  392. ;   INPUT
  393. ;   d0    vector size (without size prefix), in longwords, with memory
  394. ;    flags CHIP and FAST in bits 30 and 31
  395. ;
  396. ;   RESULT
  397. ;   a0    vector
  398. ;
  399. ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  400. GetVector:
  401.         move.l    d0,d1
  402.         lsl.l    #2,d0
  403.         addq.l    #4,d0
  404.         move.l    d0,-(a7)
  405.         addq.l    #4,d0
  406.         rol.l    #3,d1
  407.         and.l    #6,d1        ; mask to MEMF_FAST+MEMF_CHIP
  408.         move.l    lsv_AllocFunc(a5),a1
  409.         move.l    lsv_DataEnviron(a5),a6
  410.         jsr    (a1)
  411.         tst.l    d0
  412.         bne.s    gvCacheSize
  413. gFail:
  414.         addq.l    #8,a7
  415.         bra    lsFail
  416. gvCacheSize:
  417.         move.l    d0,a0
  418.         move.l    (a7)+,(a0)
  419.         addq.l    #4,a0
  420.         rts
  421.  
  422.  
  423. ;------ UnLoadSeg ----------------------------------------------------
  424. ;
  425. ;    UnLoadSeg(segment, freeFunc, dataEnviron)
  426. ;              d1       a1        a6
  427. ;
  428. ;    freeFunc(memory, size)
  429. ;             a1      d0
  430. ;
  431. ;   EXCEPTIONS
  432. ;
  433. ;---------------------------------------------------------------------
  434. UnLoadSeg:
  435.         movem.l    d2/a2,-(a7)
  436.         move.l    d1,d2
  437.         move.l    a1,a2
  438.         bra.s    usNext
  439. usLoop:
  440.         ;-- free this hunk
  441.         move.l    (a1),d2        ; cache next segment
  442.         move.l    -(a1),d0    ; get size
  443.         addq.l    #4,d0
  444.         jsr    (a2)
  445. usNext:
  446.         lsl.l    #2,d2        ; get next segment
  447.         beq.s    ulDone
  448.         move.l    d2,a1
  449.         bra.s    usLoop
  450.  
  451. ulDone:
  452.         movem.l    (a7)+,d2/a2
  453.         rts
  454.  
  455. ;------    AllocRecoverable ---------------------------------------------
  456. ;
  457. ;    memory = AllocRecoverable(size, requirements)
  458. ;    d0                        d0    d1
  459. ;
  460. ;---------------------------------------------------------------------
  461. AllocRecoverable:
  462.         movem.l    d2/d3/a2/a3/a6,-(a7)
  463.         move.l    ABSEXECBASE,a6
  464.         FORBID    a0
  465.  
  466.         ;-- get first memory header
  467.         move.l    MemList(a6),a0
  468.         moveq    #0,d3            ; guess noone big enough
  469.  
  470.         ;-- cycle through memory headers
  471. nextMemHeader:
  472.         move.l    a0,a1
  473.         move.l    (a1),d2            ; check for end of list
  474.         beq    noMemory
  475.         ;-- handle requirements
  476.         move.l    d2,a0
  477.         move.w    MH_ATTRIBUTES(a1),d2
  478.         and.w    d1,d2
  479.         cmp.w    d1,d2
  480.         bne.s    nextMemHeader
  481.  
  482.         ;-- search this memory for a big enough piece at the end
  483.         move.l    MH_FIRST(a1),a2
  484. checkMemChunk:
  485.         cmp.l    MC_BYTES(a2),d0
  486.         bhi.s    memTooSmall
  487.         move.l    a2,a3            ; this is a candidate
  488.         move.l    MC_BYTES(a2),d3        ;
  489. memTooSmall:
  490.         ;-- get the next chunk
  491.         move.l    MC_NEXT(a2),d2
  492.         beq.s    noMoreChunks
  493.         move.l    d2,a2
  494.         bra.s    checkMemChunk
  495.  
  496. noMoreChunks:
  497.         tst.l    d3            ; check for candidates
  498.         bne.s    gotChunk
  499.         bra.s    nextMemHeader
  500.  
  501. gotChunk:
  502.         sub.l    d0,d3            ; determine excess capacity
  503.         and    #(~MEM_BLOCKMASK),d3    ; rounded down to even block
  504.         add.l    d3,a3            ; and adjust desired address
  505.  
  506.         move.l    a3,a1
  507.         jsr    _LVOAllocAbs(a6)
  508. allocEnd:
  509.         PERMIT    a0
  510.         movem.l    (a7)+,d2/d3/a2/a3/a6
  511.         rts
  512.  
  513. noMemory:
  514.         moveq    #0,d0
  515.         bra.s    allocEnd
  516.  
  517.  
  518. ;------ Read ---------------------------------------------------------
  519. ;
  520. ;    actual = Read(readHandle, buffer, length)
  521. ;       d0            d1          a0      d0
  522. ;
  523. ;---------------------------------------------------------------------
  524. Read:
  525.         movem.l    d2/d3,-(a7)
  526.         move.l    a0,d2
  527.         move.l    d0,d3
  528.         jsr    _LVORead(a6)
  529.         movem.l    (a7)+,d2/d3
  530.         rts
  531.  
  532. ;------ FreeHigh -----------------------------------------------------
  533. ;
  534. ;    FreeHigh(memory, size)
  535. ;             a1      d0
  536. ;
  537. ;---------------------------------------------------------------------
  538. FreeHigh:
  539.         move.l    a6,-(a7)
  540.         move.l    ABSEXECBASE,a6
  541.         jsr    _LVOFreeMem(a6)
  542.         move.l    (a7)+,a6
  543.         rts
  544.  
  545. ;****** PrivateLoadSeg ***********************************************
  546. ;    PrivateLoadSeg(fileName)
  547. ;    
  548. ;    success = LoadSeg(allocFunc, freeFunc, readFunc,
  549. ;    d0                a0         a1        a2
  550. ;                      readHandle, dataEnviron)
  551. ;                      d1          a6
  552. ;*********************************************************************
  553. _PrivateLoadSeg:
  554.         movem.l    d2/a2/a6,-(a7)
  555.         moveq    #0,d2
  556.         lea    DLName(pc),a1
  557.         moveq    #0,d0
  558.         move.l    ABSEXECBASE,a6
  559.         jsr    _LVOOpenLibrary(a6)
  560.         tst.l    d0
  561.         beq.s    plsDone
  562.         move.l    d0,a6
  563.         move.l    16(a7),d1
  564.         move.l    #MODE_OLDFILE,d2
  565.         jsr    _LVOOpen(a6)
  566.         move.l    d0,d2
  567.         beq.s    plsCloseLib
  568.         move.l    d0,d1
  569.         lea    AllocRecoverable(pc),a0
  570.         lea    FreeHigh(pc),a1
  571.         lea    Read(pc),a2
  572.         bsr    LoadSeg
  573.         move.l    d2,d1
  574.         move.l    d0,d2
  575.         jsr    _LVOClose(a6)
  576. plsCloseLib:
  577.         move.l    a6,a1
  578.         move.l    ABSEXECBASE,a6
  579.         jsr    _LVOCloseLibrary(a6)
  580. plsDone:
  581.         move.l    d2,d0
  582.         movem.l    (a7)+,d2/a2/a6
  583.         rts
  584.  
  585. DLName        dc.b    'dos.library',0
  586.         ds.w    0
  587.     
  588.     END
  589.